/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import javax.sip.InvalidArgumentException;
import javax.sip.header.RetryAfterHeader;
import java.text.ParseException;

/**
 * The Retry-After header field identifies the time to retry the request after
 * recipt of the response. It can be used with a 500 (Server Internal Error) or 503
 * (Service Unavailable) response to indicate how long the service is
 * expected to be unavailable to the requesting client and with a 404
 * (Not Found), 413 (Request Entity Too Large), 480 (Temporarily Unavailable),
 * 486 (Busy Here), 600 (Busy), or 603 (Decline) response to indicate when the
 * called party anticipates being available again. The value of this field is
 * a positive integer number of seconds (in decimal) after the time of the
 * response.
 * <p/>
 * An optional comment can be used to indicate additional information about the
 * time of callback.  An optional "duration" parameter indicates how long the
 * called party will be reachable starting at the initial time of availability.
 * If no duration parameter is given, the service is assumed to be available
 * indefinitely.
 * <p/>
 * For Examples:<br>
 * <code>Retry-After: 18000;duration=3600<br>
 * Retry-After: 120 (I'm in a meeting)</code>
 *
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 * @see javax.sip.header.Parameters
 * @see javax.sip.header.Header
 */
public class RetryAfterHeaderImpl extends ParametrizedHeaderBase implements RetryAfterHeader {
    private final static RetryAfterHeaderParser parser = new RetryAfterHeaderParser();

    private int retryAfter;
    private String comment;

    public RetryAfterHeaderImpl() {
        super(RetryAfterHeader.NAME);
    }

    RetryAfterHeaderImpl(byte[] data, int start, int end) {
        super(RetryAfterHeader.NAME, data, start, end);
    }

    public Object clone() {
        final RetryAfterHeaderImpl header = new RetryAfterHeaderImpl();
        header.cloneBase(this);
        if (parsed) {
            header.cloneParameters(this);
            header.retryAfter = this.retryAfter;
            header.comment = this.comment;
        }
        return header;
    }

    protected HeaderParser getParser() {
        return parser;
    }

    protected String getValueAsString() {
        if (comment != null)
            return Integer.toString(retryAfter) + " (" + comment + ")";
        else
            return Integer.toString(retryAfter);
    }

    /**
     * Sets the retry after value of the RetryAfterHeader. The retry after value
     * MUST be greater than zero and MUST be less than 2**31.
     *
     * @param retryAfter the new retry after value of this RetryAfterHeader
     * @throws javax.sip.InvalidArgumentException
     *          if supplied value is less than zero.
     */

    public void setRetryAfter(int retryAfter) throws InvalidArgumentException {
        parse();
        this.retryAfter = retryAfter;
        invalidateHeaderData();
    }

    /**
     * Gets the retry after value of the RetryAfterHeader. This retry after
     * value is relative time.
     *
     * @return the retry after value of the RetryAfterHeader.
     */

    public int getRetryAfter() {
        parse();
        return this.retryAfter;
    }

    /**
     * Gets the comment of RetryAfterHeader.
     *
     * @return the comment of this RetryAfterHeader, return null if no comment
     *         is available.
     */

    public String getComment() {
        parse();
        return this.comment;
    }

    /**
     * Sets the comment value of the RetryAfterHeader.
     *
     * @param comment the new comment string value of the RetryAfterHeader.
     * @throws java.text.ParseException which signals that an error has been reached
     *                                  unexpectedly while parsing the comment.
     */

    public void setComment(String comment) throws ParseException {
        parse();
        this.comment = comment;
        invalidateHeaderData();
    }

    /**
     * Sets the duration value of the RetryAfterHeader. The retry after value
     * MUST be greater than zero and MUST be less than 2**31.
     *
     * @param duration the new duration value of this RetryAfterHeader
     * @throws javax.sip.InvalidArgumentException
     *          if supplied value is less than zero.
     */

    public void setDuration(int duration) throws InvalidArgumentException {
        try {
            setParameter("duration", Integer.toString(duration));
        } catch (ParseException e) {
            throw new InvalidArgumentException("Cannot set the duration parameter!", e);
        }
    }

    /**
     * Gets the duration value of the RetryAfterHeader. This duration value
     * is relative time.
     *
     * @return the duration value of the RetryAfterHeader, return zero if not
     *         set.
     */

    public int getDuration() {
        final String durationStr = getParameter("duration");
        int duration = 0;
        if (durationStr != null) {
            try {
                duration = Integer.parseInt(durationStr);
            } catch (Exception ex) {
            }
        }
        return duration;
    }
}
/*
 * $Log$
 */